#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@File    :   NRC22_Fun_test.py
@Time    :   2024/09/13 13:31:28
@Author  :   yangliang 
@Version :   1.0
@Contact :   yangliang@chengtech.com
@License :   (C)Copyright 2022-2025
@Desc    :   None
'''

# here put the import lib
from pytest_assume.plugin import assume

import pytest
import logging
import time
from commDriver.TS_CAN import *
import allure
import sys
import Set_up
from collections.abc import Iterable

from sqlalchemy import false
sys.dont_write_bytecode = True

Default_mode = [([0x14, 0xFF, 0xFF, 0xFF], [0x7F, 0x14, 0x22]),
                ([0x11, 0x01], [0x7F, 0x11, 0x22]),
                ([0x11, 0x03], [0x7F, 0x11, 0x22])
                ]

Extended_mode = [([0x10, 0x02], [0x7F, 0x10, 0x22]),
                 ([0x14, 0xFF, 0xFF, 0xFF], [0x7F, 0x14, 0x22]),
                 ([0x11, 0x01], [0x7F, 0x11, 0x22]),
                 ([0x11, 0x03], [0x7F, 0x11, 0x22]),
                 ([0x28, 0x03, 0x01], [0x7F, 0x28, 0x22]),
                 ([0x28, 0x03, 0x02], [0x7F, 0x28, 0x22]),
                 ([0x28, 0x03, 0x03], [0x7F, 0x28, 0x22]),
                 ([0x28, 0x02, 0x01], [0x7F, 0x28, 0x22]),
                 ([0x28, 0x02, 0x02], [0x7F, 0x28, 0x22]),
                 ([0x28, 0x02, 0x03], [0x7F, 0x28, 0x22]),
                 ([0x28, 0x01, 0x01], [0x7F, 0x28, 0x22]),
                 ([0x28, 0x01, 0x02], [0x7F, 0x28, 0x22]),
                 ([0x28, 0x01, 0x03], [0x7F, 0x28, 0x22]),
                 ([0x28, 0x00, 0x01], [0x7F, 0x28, 0x22]),
                 ([0x28, 0x00, 0x02], [0x7F, 0x28, 0x22]),
                 ([0x28, 0x00, 0x03], [0x7F, 0x28, 0x22]),
                #  ([0x85, 0x02], [0x7F, 0x85, 0x22]),      诊断调查表里0x85没有写NRC22条件，但支持的NRC有22存在，所以该如何判定?   
                #  ([0x85, 0x01], [0x7F, 0x85, 0x22])       诊断调查表里0x85没有写NRC22条件，但支持的NRC有22存在，所以该如何判定?
                 ]

Programming_mode = [([0x11, 0x01], [0x7F, 0x11, 0x22]),
                    ([0x11, 0x03], [0x7F, 0x11, 0x22])
                    ]


'''
    SpeedVD_signal 0x0: not valid
    SpeedVD_signal 0x1: valid
'''
SpeedVD_signal = Set_up.NetName, Set_up.nodeName, 'PBM_0x185', 'VehSpdVld'
SpeedACT_signal = Set_up.NetName, Set_up.nodeName, 'PBM_0x185', 'VehSpd'


@allure.severity('critical')
class Test_NRC22_Fun(object):

    def setSignalValue(self, Driver, signal_list, value):
        Driver['CAN'].write_db_signal(signal_list[0], signal_list[1], signal_list[2], signal_list[3], value)
        time.sleep(0.2)
        readValue = Driver['CAN'].read_db_signal(signal_list[0], signal_list[1], signal_list[2], signal_list[3])

    ids = ["Request {}".format(binascii.b2a_hex(bytearray(req), ' '))for req, resp in Default_mode]
    @allure.story('ECU NRC 22 Test')
    @allure.description('Test Service without unlock Undervoltage confition response NRC22 in default session with function addressing')
    @allure.testcase('https://chengtech.pingcode.com/testhub/libraries/6306e0482ce6d84a055b6e90/cases')
    @pytest.mark.parametrize('req,resp', Default_mode, ids=ids)
    def test_Undervoltage_Default_Func(self, action, Driver, req, resp):
        iStep = 1
        correctResponse = [req[0] + 0x40]
        iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, req, correctResponse, 1, iStep, False, 'UDSFun')
        time.sleep(1)
        iStep = Driver['CAN'].SetVolt(Driver, 8, 1, iStep)
        iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, req, resp, 0, iStep, False, 'UDSFun')
        iStep = Driver['CAN'].SetVolt(Driver, 12, 1, iStep)
        iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, req, correctResponse, 0, iStep, False, 'UDSFun')

    ids = ["Request {}".format(binascii.b2a_hex(bytearray(req), ' '))for req, resp in Default_mode]
    @allure.description('Test Service without unlock Undervoltage confition response NRC22 in default session with function addressing')
    @allure.testcase('https://chengtech.pingcode.com/testhub/libraries/6306e0482ce6d84a055b6e90/cases')
    @pytest.mark.parametrize('req,resp', Default_mode, ids=ids)
    def test_Overvoltage_Default_Func(self, action, Driver, req, resp):
        iStep = 1
        correctResponse = [req[0] + 0x40]
        iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, req, correctResponse, 1, iStep, False, 'UDSFun')
        time.sleep(1)
        iStep = Driver['CAN'].SetVolt(Driver, 17, 1, iStep)
        iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, req, resp, 0, iStep, False, 'UDSFun')
        iStep = Driver['CAN'].SetVolt(Driver, 12, 1, iStep)
        iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, req, correctResponse, 0, iStep, False, 'UDSFun')

    ids = ["Request {}".format(binascii.b2a_hex(bytearray(req), ' '))for req, resp in Default_mode]
    @allure.description('Test Service without unlock Vspeed over 3kph confition response NRC22 in default session with function addressing')
    @allure.testcase('https://chengtech.pingcode.com/testhub/libraries/6306e0482ce6d84a055b6e90/cases')
    @pytest.mark.parametrize('req,resp', Default_mode, ids=ids)
    def test_OverVspeed_Default_Func(self, action, Driver, req, resp):
        iStep = 1
        correctResponse = [req[0] + 0x40]
        iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, req, correctResponse, 1, iStep, False, 'UDSFun')
        time.sleep(1)
        with allure.step(f'Step{iStep}:Request:设置车速为4kph'):
            self.setSignalValue(Driver, SpeedVD_signal, 1)
            self.setSignalValue(Driver, SpeedACT_signal, 4)
            time.sleep(0.5)
            iStep += 1
        iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, req, resp, 0, iStep, False, 'UDSFun')
        with allure.step(f'Step{iStep}:Request:设置车速为0kph,并等待1s'):
            self.setSignalValue(Driver, SpeedACT_signal, 0)
            logging.info('wait 1s')
            time.sleep(1)
            iStep += 1
        iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, req, correctResponse, 0, iStep, False, 'UDSFun')

    ids = ["Request {}".format(binascii.b2a_hex(bytearray(req), ' '))for req, resp in Extended_mode]
    @allure.story('ECU NRC 22 Test')
    @allure.description('Test Service without unlock Undervoltage confition response NRC22 in extended session with function addressing')
    @allure.testcase('https://chengtech.pingcode.com/testhub/libraries/6306e0482ce6d84a055b6e90/cases')
    @pytest.mark.parametrize('req,resp', Extended_mode, ids=ids)
    def test_Undervoltage_Extended_Func(self, action, Driver, req, resp):
        iStep = 1
        correctResponse = [req[0] + 0x40]
        if req[0] == 0x10:
            iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, '31 01 02 03', '71 01 02 03', 3, iStep, False)
        elif req[0] == 0x11:
            iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, req, correctResponse, 3, iStep, False, 'UDSFun')
            time.sleep(1)
            iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, '3E 00', '7E 00', 3, iStep, False, 'UDSFun')
        else:
            iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, req, correctResponse, 3, iStep, False, 'UDSFun')
        iStep = Driver['CAN'].SetVolt(Driver, 8, 1, iStep)
        iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, req, resp, 0, iStep, False, 'UDSFun')
        iStep = Driver['CAN'].SetVolt(Driver, 12, 1, iStep)
        iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, req, correctResponse, 0, iStep, False, 'UDSFun')
        if req[0] == 0x11:
            time.sleep(1)
           

    ids = ["Request {}".format(binascii.b2a_hex(bytearray(req), ' '))for req, resp in Extended_mode]
    @allure.description('Test Service without unlock Undervoltage confition response NRC22 in extended session with function addressing')
    @allure.testcase('https://chengtech.pingcode.com/testhub/libraries/6306e0482ce6d84a055b6e90/cases')
    @pytest.mark.parametrize('req,resp', Extended_mode, ids=ids)
    def test_Overvoltage_Extended_Func(self, action, Driver, req, resp):
        iStep = 1
        time.sleep(0.5)
        correctResponse = [req[0] + 0x40]
        if req[0] == 0x10:
            iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, '31 01 02 03', '71 01 02 03', 3, iStep, False)
        elif req[0] == 0x11:
            iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, req, correctResponse, 3, iStep, False, 'UDSFun')
            time.sleep(1)
            iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, '3E 00', '7E 00', 3, iStep, False, 'UDSFun')
        else:
            iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, req, correctResponse, 3, iStep, False, 'UDSFun')
        iStep = Driver['CAN'].SetVolt(Driver, 17, 1, iStep)
        iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, req, resp, 0, iStep, False, 'UDSFun')
        iStep = Driver['CAN'].SetVolt(Driver, 12, 1, iStep)
        iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, req, correctResponse, 0, iStep, False, 'UDSFun')

    ids = ["Request {}".format(binascii.b2a_hex(bytearray(req), ' '))for req, resp in Extended_mode]
    @allure.description('Test Service without unlock Vspeed over 3kph confition response NRC22 in extended session with function addressing')
    @allure.testcase('https://chengtech.pingcode.com/testhub/libraries/6306e0482ce6d84a055b6e90/cases')
    @pytest.mark.parametrize('req,resp', Extended_mode, ids=ids)
    def test_OverVspeed_Extended_Func(self, action, Driver, req, resp):
        iStep = 1
        correctResponse = [req[0] + 0x40]
        if req[0] == 0x10:
            iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, '31 01 02 03', '71 01 02 03', 3, iStep, False)
        elif req[0] == 0x11:
            iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, req, correctResponse, 3, iStep, False, 'UDSFun')
            time.sleep(1)
            iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, '3E 00', '7E 00', 3, iStep, False, 'UDSFun')
        else:
            iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, req, correctResponse, 3, iStep, False, 'UDSFun')
        with allure.step(f'Step{iStep}:Request:设置车速为4kph'):
            self.setSignalValue(Driver, SpeedVD_signal, 1)
            self.setSignalValue(Driver, SpeedACT_signal, 4)
            time.sleep(0.5)
            iStep += 1
        if req == [0x28, 0x02, 0x01] or req == [0x28, 0x02, 0x03] or req == [0x28, 0x03, 0x01] or req == [0x28, 0x03, 0x03]:
            resp = correctResponse
        iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, req, resp, 0, iStep, False, 'UDSFun')
        with allure.step(f'Step{iStep}:Request:设置车速为0kph,并等待1s'):
            self.setSignalValue(Driver, SpeedACT_signal, 0)
            logging.info('wait 1s')
            time.sleep(0.5)
            iStep += 1
        iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, req, correctResponse, 0, iStep, False, 'UDSFun')

    # boot下电压固定12V
    # ids = ['Request {0}'.format(binascii.b2a_hex(bytearray(req), ' '))for req, resp in Programming_mode]
    # @allure.description('Test Service Undervoltage confition response NRC22 in programming session with function addressing')
    # @allure.testcase('https://chengtech.pingcode.com/testhub/libraries/6306e0482ce6d84a055b6e90/cases')
    # @pytest.mark.parametrize('req,resp', Programming_mode, ids=ids)
    # def test_Undervoltage_programming_Func(self, action, Driver, req, resp):
    #     iStep = 1
    #     correctResponse = [req[0] + 0x40]
    #     iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, req, correctResponse, 2, iStep, False, 'UDSFun')
    #     iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, '3E 00', '7E 00', 2, iStep, False, 'UDSFun')
    #     iStep = Driver['CAN'].SetVolt(Driver, 8, 1, iStep)
    #     iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, req, resp, 0, iStep, False, 'UDSFun')
    #     iStep = Driver['CAN'].SetVolt(Driver, 12, 1, iStep)
    #     iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, req, correctResponse, 0, iStep, False, 'UDSFun')

    # # boot下电压固定12V
    # ids = ['Request {0}'.format(binascii.b2a_hex(bytearray(req), ' '))for req, resp in Programming_mode]
    # @allure.description('Test Service Overvoltage confition response NRC22 in programming session with function addressing')
    # @allure.testcase('https://chengtech.pingcode.com/testhub/libraries/6306e0482ce6d84a055b6e90/cases')
    # @pytest.mark.parametrize('req,resp', Programming_mode, ids=ids)
    # def test_Overvoltage_programming_Func(self, action, Driver, req, resp):
    #     iStep = 1
    #     correctResponse = [req[0] + 0x40]
    #     iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, req, correctResponse, 2, iStep, False, 'UDSFun')
    #     time.sleep(1)
    #     iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, '3E 00', '7E 00', 2, iStep, False, 'UDSFun')

    #     iStep = Driver['CAN'].SetVolt(Driver, 17, 1, iStep)
    #     iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, req, resp, 0, iStep, False, 'UDSFun')
    #     iStep = Driver['CAN'].SetVolt(Driver, 12, 1, iStep)
    #     iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, req, correctResponse, 0, iStep, False, 'UDSFun')

    
    ids = ['Request {0}'.format(binascii.b2a_hex(bytearray(req), ' '))for req, resp in Programming_mode]
    @allure.description('Test Service with unlock Vspeed over 3kph confition response NRC22 in programming session with function addressing')
    @allure.testcase('https://chengtech.pingcode.com/testhub/libraries/6306e0482ce6d84a055b6e90/cases')
    @pytest.mark.parametrize('req,resp', Programming_mode, ids=ids)
    def test_OverVspeed_programming_Func(self, action, Driver, req, resp):
        iStep = 1
        correctResponse = [req[0] + 0x40]
        iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, req, correctResponse, 2, iStep, False, 'UDSFun')
        time.sleep(1)
        iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, '3E 00', '7E 00', 2, iStep, False, 'UDSFun')
        with allure.step(f'Step{iStep}:Request:设置车速为4kph'):
            self.setSignalValue(Driver, SpeedVD_signal, 1)
            self.setSignalValue(Driver, SpeedACT_signal, 4)
            iStep += 1
        iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, req, resp, 0, iStep, False, 'UDSFun')
        with allure.step(f'Step{iStep}:Request:设置车速为0kph,并等待1s'):
            self.setSignalValue(Driver, SpeedACT_signal, 0)
            logging.info('wait 1s')
            time.sleep(1)
            iStep += 1
        iStep, uds_resp, size = Driver['CAN'].checkReqResp(Driver, req, correctResponse, 0, iStep, False, 'UDSFun')
